9. UC-SLS Lecture 9 : Assembly : Operations and Data Types¶
9.1. A simple mov.S program¶
9.1.1. Setup¶
create a directory
mkdir mov; cd movcreate and write
mov.Sbelowadd a
Makefileto automate assembling and linkingwe are going run the commands by hand this time to highlight the details
add our
setup.gdbto make working in gdb easiernormally you would want to track everything in git
CODE: asm - mov.S
.intel_syntax noprefix
.text
.equ EXIT_SYSCALL_NR,60
.global _start
.type _start, @function
_start:
mov rax, 0b1000
mov rax, EXIT_SYSCALL_NR
mov rdi, 2
syscall
9.1.2. Assemble mov.S into mov.o directly with assembler (as)¶
-aproduce listing to standard outwe could add
-gflag to add extra debugger information but lets skip it for now
rm: cannot remove 'mov.o': No such file or directory
as -a=mov.o.lst mov.S -o mov.o
9.1.2.1. mov.o is NOT an executable¶
$ ls -l mov.o
-rw-r--r-- 1 jovyan root 752 Nov 4 16:31 mov.o
9.1.2.2. What kind of file is is it?¶
$ file mov.o
mov.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
9.1.2.3. Examine Symbol Table¶
$ objdump -t mov.o
mov.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
000000000000003c l *ABS* 0000000000000000 EXIT_SYSCALL_NR
0000000000000000 g F .text 0000000000000000 _start
9.1.3. Link mov.o to produce the binary mov with linker (ld)¶
we don’t really have any other files to link
simply need to have linker organize things as per os linker script (use
ld -verboseto see the script )note the syntax is very cryptic
ld -g -Map=mov.map mov.o -o mov
$ ls -l mov
-rwxr-xr-x 1 jovyan root 4712 Nov 4 16:31 mov
$ file mov.o
mov: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ objdump -t mov
mov: file format elf64-x86-64
SYMBOL TABLE:
0000000000401000 l d .text 0000000000000000 .text
0000000000000000 l df *ABS* 0000000000000000 mov.o
000000000000003c l *ABS* 0000000000000000 EXIT_SYSCALL_NR
0000000000401000 g F .text 0000000000000000 _start
0000000000402000 g .text 0000000000000000 __bss_start
0000000000402000 g .text 0000000000000000 _edata
0000000000402000 g .text 0000000000000000 _end
$ ld --verbose
GNU ld (GNU Binutils for Ubuntu) 2.34
Supported emulations:
elf_x86_64
elf32_x86_64
elf_i386
elf_iamcu
elf_l1om
elf_k1om
i386pep
i386pe
using internal linker script:
==================================================
/* Script for -z combreloc -z separate-code */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib");
SECTIONS
{
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = D$
9.1.3.1. recognize anything?¶
9.1.3.2. lets run it¶
$ ./mov
$ echo $?
2
9.1.3.3. We can use tools to convert the executable into a binary image¶
objcopyis a very useful tool likeobjdumplet’s us convert the executable into various formats including
rawbinaryobjcopy mov --output-target=binary mov.bin
objcopy mov --output-target=binary mov.bin
hexdump -C mov.bin
00000000 48 c7 c0 08 00 00 00 48 c7 c0 3c 00 00 00 48 c7 |H......H..<...H.|
00000010 c7 02 00 00 00 0f 05 |.......|
00000017